var GameBase = require('geoGameBase');
var UIStartDialog = require('geoUIStartDialog');
var UIResultDialog = require('geoUIResultDialog');
var Utils = require('geoUtils');

cc.Class({
    extends: GameBase,

    properties: {
        titleVoice: {
            default: null,
            type: cc.AudioClip,
            tooltip: '游戏标题语音'
        },
        gameTitle: '游戏标题名称',
        gameDesc: {
            default: '游戏介绍文字',
            multiline: true,
        },
        bgMusic: {
            default: null,
            type: cc.AudioClip,
            tooltip: '背景音乐',
        },
        completeMusic: {
            default: null,
            type: cc.AudioClip,
            tooltip: '结束音乐',
        },
        startDialogPrefab: {
            default: null,
            type: cc.Prefab,
        },
        startDialogContainer: {
            default: null,
            type: cc.Node,
        },
        resultDialogPrefab: {
            default: null,
            type: cc.Prefab,
        },
        resultDialogContainer: {
            default: null,
            type: cc.Node,
        },
        gameStartEvents: {
            default: [],
            type: [cc.Component.EventHandler],
        },
        precreatePrefabs: {
            default: [],
            type: [cc.Prefab],
        },
        marginDecorPrefab: {
            default: null,
            type: cc.Prefab,
            tooltip: '用来填补两边的修饰物预制'
        },
        marginDecorNode: {
            default: null,
            type: cc.Node,
            tooltip: '用来生成装饰边的节点，一般是场景最前面的节点'
        },
        saveWithReport: {
            default: false,
            tooltip: '保存时是否报告保存状态'
        },
        saveGameTimeUp: {
            default: 20,
            visible: false,
            tooltip: '保存游戏超时设置'
        },
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad() {
        //
        this.precreatePrefabs.forEach(element => {
            cc.director.getScene().addChild(cc.instantiate(element));
        });
        // 因为父类要用的前面初始化中的物体，所以放在后面调用
        this._super();
    },

    start() {
        // 生成装饰边
        if (this.marginDecorPrefab != null) {
            var decor = cc.instantiate(this.marginDecorPrefab);
            var decorRoot = this.marginDecorNode || cc.director.getScene().getComponentInChildren(cc.Canvas).node;
            decorRoot.addChild(decor);
        }
        // 设置默认音量
        this.audio.setMusicVolumn(0.25);
        // 弹出开始对话框
        this.showStartDialog(true);
    },
    /**
     * 显示或隐藏开始对话框
     * @param {*} bShow 
     */
    showStartDialog(bShow) {
        if (bShow == true) {
            // 创建开始对话框
            var dlgNode = this.ui.open(this.startDialogPrefab, true, this.startDialogContainer);
            // 获取对话框组件
            var dlg = dlgNode.getComponent(UIStartDialog);
            // 设置标题和描述
            dlg.setTitle(this.gameTitle);
            dlg.setDesc(this.gameDesc);
            // 设置回调
            dlg.setStartButtonCallback(this._startGameOnStartButtonClick.bind(this));
            dlg.setCloseButtonCallback(this._closeGameOnCloseButtonClick.bind(this));
            //
            this._startDialog = dlg;
            // 不再一开场即播放标题语音
            return;
            // 播放游戏标题语音
            if (this.titleVoice != null) {
                // 开启屏蔽
                // this.ui.maskInteraction(dlgNode, true);
                this._isPlayingTitleVoice = true;
                // 播放完语音再取消屏蔽
                this.audio.playVoice(this.titleVoice, false, 1,
                    // this.ui.maskInteraction.bind(this.ui, dlgNode, false));
                    this.onTitleVoiceComplete.bind(this));
            }
        } else {
            if (this._startDialog)
                this.ui.close(this._startDialog);
            this._startDialog = null;
        }
    },
    /**
     * 标题语播放完毕时调用
     */
    onTitleVoiceComplete() {
        this._isPlayingTitleVoice = false;
        // 如果已经点击过开始游戏按钮，则开始游戏
        if (this._isStartGameButtonClicked === true)
            this._startGame();
    },
    /**
     * 显示或隐藏结束对话框
     * @param {*} bShow 
     */
    showResultDialog(bShow) {
        if (bShow == true) {
            // 创建开始对话框
            var dlgNode = this.ui.open(this.resultDialogPrefab, true, this.resultDialogContainer);
            // 获取对话框组件
            var dlg = dlgNode.getComponent(UIResultDialog);
            // 设置回调
            dlg.setReplayButtonCallback(this._replayGame.bind(this));
            dlg.setCloseButtonCallback(this._closeGame.bind(this));
            //
            this._resultDialog = dlg;
            // 停止一切音乐播放
            this.audio.stopMusic();
            // 播放完成音乐
            this.audio.playMusic(this.completeMusic, false, 1);
        } else {
            if (this._resultDialog)
                this.ui.close(this._resultDialog);
            this._resultDialog = null;
        }
    },
    /**
     * 设置结果对话框中的得分
     * @param {*} score 
     */
    setResultScore(score, complete, step) {
        // 
        this.saveResultScore(score);
        //
        this._resultDialog.setScore(score, complete, step);
    },
    /**
     * 设置顶栏中的分数
     * @param {*}} score 
     * @param {*} complete 
     * @param {*} step 
     */
    setTopBarScore(score, complete, step) {
        this.topBar.setScore(score, complete, step);
    },
    /**
     * 设置顶栏中丢分效果
     * @param {*} scores 
     * @param {*} complete 
     * @param {*} step 
     */
    loseTopBarScore(scores, complete, step) {
        this.topBar.loseScore(scores, complete, step);
    },
    /**
     * 保存成绩
     * @param {void 0 | int} score 
     */
    saveResultScore(score) {
        this._score = (score === void 0) ? this._score : score;
        //
        if (this.saveWithReport === false) {
            Utils.sys.saveGame(score);
        } else {
            // 定义保存超时
            this._handleSaveGameTimeUp = this._onSaveGameTimeUp.bind(this);
            this.scheduleOnce(this._handleSaveGameTimeUp, this.saveGameTimeUp);
            // 尝试保存得分
            Utils.sys.saveGame(score,
                this._onSaveGameComplete.bind(this, true),
                this._onSaveGameComplete.bind(this, false));
        }
    },
    onDestroy() {
        this.audio.stopAll();
    },
    _startGame() {
        // 清理可能残存全局数据
        // this.data = {};
        // 关闭开始对话框
        this.showStartDialog(false);
        // 触发开始脚本
        cc.Component.EventHandler.emitEvents(this.gameStartEvents, this);
        // 播放背景音乐
        this.bgMusic && this.audio.playMusic(this.bgMusic, true, 1);
    },
    _replayGame() {
        // 停止所有音乐
        this.audio.stopMusic();
        // 重新加载此场景
        cc.director.loadScene(cc.director.getScene().name);
    },
    _closeGame() {
        cc.log('close game..., just back to previous page now...');
        // window.history.back();
        // window.close();
        Utils.sys.quitGame();
    },
    _startGameOnStartButtonClick() {
        this._isStartGameButtonClicked = true;
        //
        if (this._isPlayingTitleVoice === true)
            return;
        //
        if (this.titleVoice) {
            this._isPlayingTitleVoice = true;
            this.audio.playVoice(this.titleVoice, 1, 1, this.onTitleVoiceComplete.bind(this));
        } else {
            this._startGame();
        }
    },
    _closeGameOnCloseButtonClick(){
        this._closeGame();
    },
    /**
     * 保存超时时调用
     */
    _onSaveGameTimeUp() {
        // 取消超时标志
        this._handleSaveGameTimeUp = null;
        // 弹出保存失败提示
        this._openSaveGameFailDialog('保存数据超时');
    },
    /**
     * 保存操作完毕调用
     * @param {bool}} bOk 是否保存成功
     */
    _onSaveGameComplete(bOk) {
        // 解除可能的超时调用
        if (this._handleSaveGameTimeUp != null)
            this.unschedule(this._handleSaveGameTimeUp);
        this._handleSaveGameTimeUp = null;
        // 如果失败，弹出失败对话框
        if (bOk == false)
            this._openSaveGameFailDialog('保存数据失败');
    },
    /**
     * 弹出保存失败对话框
     */
    _openSaveGameFailDialog(title) {
        let msg = '数据保存失败。\n您可以选择重试或者放弃本次成绩。';
        // 创建对话框
        this.ui.openDialog(true)
            .setTitle(title)
            .setMessage(msg)
            .addCloseButton('重试', this.saveResultScore.bind(this))
            .addCloseButton('放弃');
    },
});
